package com.demo.common.email.processor;

import com.demo.common.email.config.EmailProperties;
import com.demo.common.email.config.EnableFxwEmailServer;
import com.demo.common.email.service.ISendMsgHandle;
import lombok.SneakyThrows;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.lang.reflect.Constructor;

/**
 * @author DayDayUp
 * create on 2023-08-25
 **/

public class EmailBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware {

    private static ApplicationContext applicationContext;
    @Resource
    private JavaMailSender javaMailSender;
    @Resource
    private EmailProperties emailProperties;

    @Override
    public void setApplicationContext(ApplicationContext context) throws BeansException {
        applicationContext = context;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }

    @SneakyThrows
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        EnableFxwEmailServer annotation = AnnotationUtils.findAnnotation(bean.getClass(), EnableFxwEmailServer.class);
        if (annotation != null) {
            Class<? extends ISendMsgHandle> strategy = annotation.emailHandle();
            Constructor<? extends ISendMsgHandle> constructor = strategy.getConstructor(JavaMailSender.class,EmailProperties.class);
            ISendMsgHandle sendMsgHandle = constructor.newInstance(javaMailSender,emailProperties);
            String strategyBeanName = StringUtils.uncapitalize(ISendMsgHandle.class.getSimpleName());
            registerSingletonBean(strategyBeanName,sendMsgHandle);
        }
        return bean;
    }

    /**
     * 动态注入bean
     *
     * @param requiredType 注入类
     * @param beanName     bean名称
     */
    public static Object registerBean(Class<?> requiredType, String beanName) {
        //将applicationContext转换为ConfigurableApplicationContext
        ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) applicationContext;
        //获取BeanFactory
        DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableApplicationContext.getAutowireCapableBeanFactory();
        //创建bean信息.
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(requiredType);
        //动态注册bean.
        defaultListableBeanFactory.registerBeanDefinition(beanName, beanDefinitionBuilder.getBeanDefinition());
        //获取动态注册的bean.
        return configurableApplicationContext.getBean(requiredType);
    }

    /**
     *  动态注入单例bean实例
     * @param beanName bean名称
     * @param singletonObject 单例bean实例
     */
    public void registerSingletonBean(String beanName,Object singletonObject){

        //将applicationContext转换为ConfigurableApplicationContext
        ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) applicationContext;
        //获取BeanFactory
        DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableApplicationContext.getAutowireCapableBeanFactory();
        //动态注册bean.
        defaultListableBeanFactory.registerSingleton(beanName,singletonObject);
        // 获取动态注册的bean.
        // configurableApplicationContext.getBean(beanName);
    }
}
